package org.yaukie.core.impl;

import java.text.ParseException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaukie.ClassCacheFactory;
import org.yaukie.core.BaseJob;
import org.yaukie.core.anotation.MyJob;
import org.yaukie.core.anotation.MyJob.JobType;
import org.yaukie.core.api.MyJobInter;
import org.yaukie.helper.ConfigHelper;

public class MyJobInstance extends MyAbstractJob implements MyJobInter {
    private static final Logger log = LoggerFactory.getLogger(MyJobInstance.class);

    public MyJobInstance() {
    }

    public void startJob(Class jobClass, String cron) {
        if (!this.getJobStatus(jobClass)) {
            Trigger trigger = this.createJobTrigger(jobClass, cron);
            JobDetail jobDetail = createJobDetail(jobClass);
            this.doStartJob(jobClass, jobDetail, trigger);
        }
    }

    public void startJob(Class jobClass, int seconds) {
        this.startJob(jobClass, 0, seconds);
    }

    public void startJob(Class jobClass, int count, int seconds) {
        this.startJob(jobClass, count, seconds, (String)null, (String)null);
    }

    public void startJob(Class jobClass, int count, int seconds, String start, String end) {
        Trigger trigger = this.createJobSimpleTriger(jobClass, count, seconds, start, end);
        JobDetail jobDetail = createJobDetail(jobClass);
        this.doStartJob(jobClass, jobDetail, trigger);
    }

    public void startAllJob() {
        List<Class<?>> classList = ClassCacheFactory.getClassSupportApi().getClassListBySuper(ConfigHelper.getAppBasePackage(), BaseJob.class);
        if (null != classList && classList.size() > 0) {
            log.debug("检测到总共【" + classList.size() + "】个定时任务！");

            for(int index = 0; index < classList.size(); ++index) {
                Class cls = (Class)classList.get(index);
                if (cls.isAnnotationPresent(MyJob.class)) {
                    log.debug("正在启动第" + (index + 1) + "个，[ " + cls.getSimpleName() + " ]定时任务");
                    MyJob job = (MyJob)cls.getAnnotation(MyJob.class);
                    MyJob.JobType jobType = job.jobType();
                    if (jobType.equals(JobType.CRON)) {
                        String cron = job.value();
                        this.startJob(cls, cron);
                    } else if (jobType.equals(JobType.TIMER)) {
                        this.startJob(cls, job.count(), job.seconds(), job.start(), job.end());
                    }
                }
            }
        }

    }

    public void stopJob(Class jobClass) {
        Scheduler scheduler = (Scheduler)schedulerMap.get(jobClass);

        try {
            scheduler.shutdown(true);
            schedulerMap.remove(jobClass);
        } catch (SchedulerException var4) {
            log.error("shutdown job " + jobClass.getSimpleName() + " error ");
        }

    }

    public void stopAllJob() {
        if (log.isDebugEnabled()) {
            log.debug("shutdown all jobs start....");
        }

        Iterator var1 = schedulerMap.entrySet().iterator();

        while(var1.hasNext()) {
            Map.Entry<Class, Scheduler> entry = (Map.Entry)var1.next();
            Class jobClass = (Class)entry.getKey();
            Scheduler scheduler = (Scheduler)entry.getValue();

            try {
                scheduler.shutdown(true);
                schedulerMap.remove(jobClass);
            } catch (SchedulerException var6) {
                log.error("shutdown job " + jobClass.getSimpleName() + " error ");
            }
        }

        if (log.isDebugEnabled()) {
            log.debug("shutdown all jobs end ....");
        }

    }

    public void pauseJob(Class jobClass) throws SchedulerException {
        if (schedulerMap.containsKey(jobClass)) {
            Scheduler scheduler = (Scheduler)schedulerMap.get(jobClass);
            scheduler.pauseJob(new JobKey(jobClass.getName()));
        }

    }

    public void resumeJob(Class jobClass) throws SchedulerException {
        if (schedulerMap.containsKey(jobClass)) {
            Scheduler scheduler = (Scheduler)schedulerMap.get(jobClass);
            scheduler.resumeJob(new JobKey(jobClass.getName()));
        }

    }

    private static JobDetail createJobDetail(Class jobClass) {
        return JobBuilder.newJob(jobClass).withIdentity(jobClass.getName()).build();
    }

    private SimpleTrigger createJobSimpleTriger(Class jobClass, int count, int seconds) {
        return this.createJobSimpleTriger(jobClass, count, seconds, (String)null, (String)null);
    }

    private SimpleTrigger createJobSimpleTriger(Class jobClass, int seconds) {
        return this.createJobSimpleTriger(jobClass, 0, seconds, (String)null, (String)null);
    }

    SimpleTrigger doCreateJobSimpleTrigger(TriggerBuilder<SimpleTrigger> triggerBuilder, String start, String end) {
        if (StringUtils.isNotEmpty(start)) {
            try {
                triggerBuilder.startAt(DateUtils.parseDate(start, new String[]{"yyyy-MM-dd HH:mm:ss"}));
            } catch (ParseException var6) {
                var6.printStackTrace();
            }
        }

        if (StringUtils.isNotEmpty(start)) {
            try {
                triggerBuilder.startAt(DateUtils.parseDate(end, new String[]{"yyyy-MM-dd HH:mm:ss"}));
            } catch (ParseException var5) {
                var5.printStackTrace();
            }
        }

        return (SimpleTrigger)triggerBuilder.build();
    }

    public Scheduler createScheduler(JobDetail jobDetail, Trigger trigger) throws SchedulerException {
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
        scheduler.setJobFactory(new JobFactory() {
            public Job newJob(TriggerFiredBundle triggerFiredBundle, Scheduler scheduler) throws SchedulerException {
                JobDetail jobDetail = triggerFiredBundle.getJobDetail();
                Class jobClass = jobDetail.getJobClass();

                try {
                    return (Job)jobClass.newInstance();
                } catch (InstantiationException var6) {
                    var6.printStackTrace();
                } catch (IllegalAccessException var7) {
                    var7.printStackTrace();
                }

                return null;
            }
        });
        scheduler.scheduleJob(jobDetail, trigger);
        return scheduler;
    }

    Scheduler getScheduler(Class jobClass) {
        Scheduler scheduler = null;
        if (schedulerMap.containsKey(jobClass)) {
            scheduler = (Scheduler)schedulerMap.get(jobClass);
        }

        return scheduler;
    }
}
